package com.spark.gaea.quartz.examples;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.quartz.SchedulerException;
import org.quartz.utils.ConnectionProvider;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;

public class MyPoolingconnectionProvider implements ConnectionProvider {
	public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;
	public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;
	private String driver;
	private String url;
	private String user;
	private String password;
	private int maxConnections;
	private int maxCachedStatementsPerConnection;
	private int maxIdleSeconds;
	private String validationQuery;
	private int idleConnectionValidationSeconds;
	private boolean validateOnCheckout;
	private String discardIdleConnectionsSeconds;
	private ComboPooledDataSource datasource;

	@Override
	public Connection getConnection() throws SQLException {
		return this.datasource.getConnection();
	}

	@Override
	public void shutdown() {
		this.datasource.close();
	}

	@Override
	public void initialize() throws SQLException {
		if (this.url == null) {
			throw new SQLException("DBPool could not be created: DB URL cannot be null");
		}
		if (this.driver == null) {
			throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");
		}
		if (this.maxConnections < 0) {
			throw new SQLException(
					"DBPool maxConnectins could not be created: Max connections must be greater than zero!");
		}
		this.datasource = new ComboPooledDataSource();
		try {
			this.datasource.setDriverClass(this.driver);
		} catch (PropertyVetoException e) {
			try {
				throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);
			} catch (SchedulerException ex) {}
		}
		this.datasource.setJdbcUrl(this.url);
		this.datasource.setUser(this.user);
		this.datasource.setPassword(this.password);
		this.datasource.setMaxPoolSize(this.maxConnections);
		this.datasource.setMinPoolSize(1);
		this.datasource.setMaxIdleTime(this.maxIdleSeconds);
		this.datasource.setMaxStatementsPerConnection(this.maxCachedStatementsPerConnection);
		if (this.validationQuery != null) {
			this.datasource.setPreferredTestQuery(this.validationQuery);
			if (!this.validateOnCheckout) {
				this.datasource.setTestConnectionOnCheckin(true);
			} else {
				this.datasource.setTestConnectionOnCheckout(true);
			}
			this.datasource.setIdleConnectionTestPeriod(this.idleConnectionValidationSeconds);
		}
	}

	public static int getDefaultDbMaxConnections() {
		return 10;
	}

	public static int getDefaultDbMaxCachedStatementsPerConnection() {
		return 120;
	}

	public String getDriver() {
		return this.driver;
	}

	public void setDriver(final String driver) {
		this.driver = driver;
	}

	public String getUrl() {
		return this.url;
	}

	public void setUrl(final String url) {
		this.url = url;
	}

	public String getUser() {
		return this.user;
	}

	public void setUser(final String user) {
		this.user = user;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(final String password) {
		this.password = password;
	}

	public int getMaxConnections() {
		return this.maxConnections;
	}

	public void setMaxConnections(final int maxConnections) {
		this.maxConnections = maxConnections;
	}

	public int getMaxCachedStatementsPerConnection() {
		return this.maxCachedStatementsPerConnection;
	}

	public void setMaxCachedStatementsPerConnection(final int maxCachedStatementsPerConnection) {
		this.maxCachedStatementsPerConnection = maxCachedStatementsPerConnection;
	}

	public int getMaxIdleSeconds() {
		return this.maxIdleSeconds;
	}

	public void setMaxIdleSeconds(final int maxIdleSeconds) {
		this.maxIdleSeconds = maxIdleSeconds;
	}

	public String getValidationQuery() {
		return this.validationQuery;
	}

	public void setValidationQuery(final String validationQuery) {
		this.validationQuery = validationQuery;
	}

	public int getIdleConnectionValidationSeconds() {
		return this.idleConnectionValidationSeconds;
	}

	public void setIdleConnectionValidationSeconds(final int idleConnectionValidationSeconds) {
		this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;
	}

	public boolean isValidateOnCheckout() {
		return this.validateOnCheckout;
	}

	public void setValidateOnCheckout(final boolean validateOnCheckout) {
		this.validateOnCheckout = validateOnCheckout;
	}

	public String getDiscardIdleConnectionsSeconds() {
		return this.discardIdleConnectionsSeconds;
	}

	public void setDiscardIdleConnectionsSeconds(final String discardIdleConnectionsSeconds) {
		this.discardIdleConnectionsSeconds = discardIdleConnectionsSeconds;
	}

	public ComboPooledDataSource getDatasource() {
		return this.datasource;
	}

	public void setDatasource(final ComboPooledDataSource datasource) {
		this.datasource = datasource;
	}
}
